package com.legstar.talend.xsd2xml;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.thoughtworks.xstream.XStream;

/**
 * Prints out a set of TOS schemas.
 * 
 */
public class Cob2TosSchemaWriter {

    /** Assume TOS schemas are always UTF-8 encoded. */
    private static final String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    /** All TOS schemas encoded as UTF-8. */
    private static final String TOS_SCHEMA_ENCODING = "UTF-8";

    /** All TOS schemas are xml files. */
    private static final String TOS_SCHEMA_EXTENSION = ".xml";

    /** The set of TOS schemas to serialize. */
    private Map<String, TosSchema> _tosSchemas;

    /** Logger. */
    private final Log _log = LogFactory.getLog(getClass());

    /**
     * Construct from a TOS schema.
     * 
     * @param tosSchemas the set of TOS schema.
     */
    public Cob2TosSchemaWriter(final Map<String, TosSchema> tosSchemas) {
        _tosSchemas = tosSchemas;
    }

    /**
     * Serialize the TOS schemas in XML strings.
     */
    public Map<String, String> toStrings() {
        Map<String, String> strings = new HashMap<String, String>();
        for (Entry<String, TosSchema> entry : getTosSchemas().entrySet()) {
            strings.put(entry.getKey(), toString(entry.getValue()));
        }
        return strings;
    }

    /**
     * Serialize an TOS schema to an XML string.
     */
    public String toString(final TosSchema tosSchema) {
        StringWriter writer = new StringWriter();
        writer.append(XML_DECLARATION + '\n');
        XStream xstream = new XStream();
        xstream.processAnnotations(TosSchema.class);
        xstream.toXML(tosSchema, writer);
        return writer.toString();
    }

    /**
     * Serialize a set of TOS schemas to files.
     * <p/>
     * The files are named using the hint provided followed by a schema
     * identifier if there is any.
     * 
     * @param outputFolder the output folder to receive TOS schemas
     * @param hintBaseName the name to use as base for output files
     * @return the list of files produced
     * @throws IOException if writing fails
     */
    public List<File> toFiles(final File outputFolder, final String hintBaseName)
            throws IOException {
        List<File> outputFiles = new ArrayList<File>();
        for (Entry<String, TosSchema> entry : getTosSchemas().entrySet()) {
            File file = new File(outputFolder, hintBaseName
                    + ((entry.getKey().length() == 0) ? "" : "_"
                            + entry.getKey()) + TOS_SCHEMA_EXTENSION);
            FileUtils.writeStringToFile(file, toString(entry.getValue()),
                    TOS_SCHEMA_ENCODING);
            outputFiles.add(file);
            if (_log.isDebugEnabled()) {
                _log.debug("Produced TOS schema in file " + file);
            }
        }
        return outputFiles;

    }

    /**
     * @return the set of TOS schemas
     */
    public Map<String, TosSchema> getTosSchemas() {
        return _tosSchemas;
    }

}
